package com.wjx.android.wanandroidmvvm.module.home.viewmodel

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.wjx.android.wanandroidmvvm.network.initiateRequest
import com.wjx.android.wanandroidmvvm.module.common.model.Article
import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel
import com.wjx.android.wanandroidmvvm.module.home.model.BannerResponse
import com.wjx.android.wanandroidmvvm.module.home.model.HomeArticleResponse
import com.wjx.android.wanandroidmvvm.module.home.repository.HomeRepository
import com.wjx.android.wanandroidmvvm.network.ResultState
import com.wjx.android.wanandroidmvvm.network.request
import com.wjx.android.wanandroidmvvm.network.toResult
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

/**
 * Created with Android Studio.
 * Description:
 * @author: Wangjianxian
 * @date: 2020/02/26
 * Time: 10:49
 */
class HomeViewModel :
    ArticleViewModel<HomeRepository>() {
    private val TAG = "HomeViewModel"
    // Rxjava2版本
//    val mBannerData: MutableLiveData<BaseResponse<List<BannerResponse>>> = MutableLiveData()
//    val mHomeArticleData: MutableLiveData<BaseResponse<HomeArticleResponse>> = MutableLiveData()
//    val mTopArticleData: MutableLiveData<BaseResponse<List<Article>>> = MutableLiveData()

//    fun loadBanner() {
//        mRepository.loadBanner(mBannerData)
//    }

//    fun loadHomeArticleData(pageNum: Int) {
//        if (pageNum == 0) {
//            mRepository.loadTopArticle(mTopArticleData)
//        }
//        mRepository.loadHomeArticle(pageNum, mHomeArticleData)
//    }

//    fun loadTopArticle() {
//        mRepository.loadTopArticle(mTopArticleData)
//    }

    // 使用协程 + Retrofit2.6以上版本
    //var mBannerData: MutableLiveData<List<BannerResponse>> = MutableLiveData()
    //var mHomeArticleData: MutableLiveData<HomeArticleResponse> = MutableLiveData()
    //var mTopArticleData: MutableLiveData<List<Article>> = MutableLiveData()

//    fun loadBannerCo() {
//        initiateRequest({
//            mBannerData.value = mRepository.loadBannerCo()
//        }, loadState)
//    }

//    fun loadBannerCo() {
//        request({ mRepository.loadBannerCo() }, mBannerData)
//    }

//    fun loadHomeArticleDataCo(pageNum: Int) {
//        initiateRequest({
//            mHomeArticleData.value = mRepository.loadHomeArticleCo(pageNum)
//            if (pageNum == 0) {
//                mTopArticleData.value = mRepository.loadTopArticleCo()
//            }
//        }, loadState)
//    }

    var mBannerData: MutableLiveData<ResultState<List<BannerResponse>>> = MutableLiveData()
    var mHomeArticleData: MutableLiveData<ResultState<HomeArticleResponse>> = MutableLiveData()
    var mLoadState: MutableLiveData<ResultState<*>> = MutableLiveData()

    fun loadHomeArticleDataCo(pageNum: Int) {
        if (pageNum == 0) {
            loadHomeData()
        } else {
            request({ mRepository.loadHomeArticleCo(pageNum) }, mHomeArticleData)
        }
    }

    private fun loadHomeData() {
        val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
            Log.e(TAG, "${throwable.message}")
            mLoadState.value = ResultState.Error(message = "网络异常")
        }
        viewModelScope.launch(exceptionHandler) {
            // 启动三个并行任务
            val bannerDeferred = async { mRepository.loadBannerCo() }
            val topArticleDeferred = async { mRepository.loadTopArticleCo() }
            val homeArticleDeferred = async { mRepository.loadHomeArticleCo(0) }
            // 等待所有任务完成并获取结果（挂起函数调用必须在协程体内）
            val bannerResult = bannerDeferred.await()
            val topArticleResult = topArticleDeferred.await()
            val homeArticleResult = homeArticleDeferred.await()
            if (bannerResult is ResultState.Success && topArticleResult is ResultState.Success && homeArticleResult is ResultState.Success) {
                mBannerData.value = bannerResult
                //
                val articleList = topArticleResult.data
                articleList.let {
                    for (article in it) {
                        article.top = true
                    }
                }
                val mergedList = articleList + homeArticleResult.data.datas
                homeArticleResult.data.datas = mergedList
                mHomeArticleData.value = homeArticleResult
                //
                mLoadState.value = ResultState.Success("")
            } else {
                if (bannerResult is ResultState.Error) {
                    mLoadState.value = bannerResult
                }
                if (topArticleResult is ResultState.Error) {
                    mLoadState.value = topArticleResult
                }
                if (homeArticleResult is ResultState.Error) {
                    mLoadState.value = homeArticleResult
                }
            }
        }
    }
}